#include <header.h>

/* Usage:  */
typedef struct connect_client{
    int fd;
    time_t last_dig_time;
}connect_c;
time_t now;
int SendToEveryone(int *size,connect_c fds[],fd_set* cur_set,fd_set* source_set){
    for(int i=0;i<*size;i++)
    {
        int tempFD=fds[i].fd;
        if(FD_ISSET(tempFD,cur_set))
        {
            char buf[100]={0};
            int res_recv=recv(tempFD,buf,sizeof(buf),0);
            time(&now);
            ERROR_CHECK(res_recv,-1,"recv");
            if(res_recv==0){
                fds[i]=fds[*size];
                FD_CLR(tempFD,source_set);
                close(tempFD);
                (*size)--;
                i--;
                printf("%d断开连接\n",tempFD);

                continue;

            }
            fds[i].last_dig_time=now;
            printf("%d发了消息\n",tempFD);
            for(int j=0;j<*size;j++)
            {
                if(i!=j)
                {
                    int res_send=send(fds[j].fd,buf,sizeof(buf),0);
                    ERROR_CHECK(res_send,-1,"send");
                }
            }
        }
    }
    return 1;
}
int CheckOutTimeClient(int *size,connect_c fds[],fd_set*source_set)
{
    for(int i=0;i<*size;i++)
    {
        int tempFD=fds[i].fd;
        time(&now); 
        if(now-fds[i].last_dig_time>20){
            printf("当前时间%ld\n",now);
            printf("上次会话时间%ld\n",fds[i].last_dig_time);
            (*size)--;
            fds[i]=fds[*size];
            FD_CLR(tempFD,source_set);
            close(tempFD);
            i--;
            printf("%d断开连接\n",tempFD);
            sleep(1);
        }
    }
    return 1;
}
void AcceptNewClient(int *size,connect_c clients[],int socketFD,fd_set *source_set){
    int newfd=accept(socketFD,NULL,NULL);
    time(&now);
    clients[*size].fd=newfd;
    clients[*size].last_dig_time=now;

    FD_SET(newfd,source_set);
    (*size)++;
    printf("size大小为%d\n",*size);
    printf("有新链接进来fd=%d\n",newfd);


}

void  InitSocketAdd(int domain,char* IP,char* Port,struct sockaddr_in *socketAddr){
    socketAddr->sin_family=domain;//TCP
    socketAddr->sin_addr.s_addr=inet_addr(IP);//IP
    socketAddr->sin_port=htons(atoi(Port));

}
int main(int argc, char *argv[]){                                  

    char *Port="8080";//监听端口
    char *IP="0.0.0.0";//本机IP

    //创建套接字
    int socketFD=socket(AF_INET,SOCK_STREAM,0);

    //创建套接字的地址信息
    struct sockaddr_in socketAddr;
    InitSocketAdd(AF_INET,IP,Port,&socketAddr);

    int reuse = 1;
    setsockopt(socketFD, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));//允许端口重复占用

    int res_bind =bind(socketFD,(struct sockaddr*)&socketAddr,sizeof(socketAddr));//绑定到套接字
    ERROR_CHECK(res_bind,-1,"bind");                                                                                  

    //监听端口
    listen(socketFD,10);

    fd_set source_set;
    FD_ZERO(&source_set);
    FD_SET(socketFD,&source_set);

    connect_c clients[1024];//用来记录已建立的连接
    memset(clients,0,sizeof(clients));//初始化
    int size=0;//标记已建立的连接数

    struct timeval waittime;//设置超时等待时间为1秒
    waittime.tv_sec=1;
    waittime.tv_usec=0;

    while(1){

        fd_set cur_set;
        memcpy(&cur_set, &source_set, sizeof(source_set));
        select(10,&cur_set,NULL,NULL,&waittime);
        //如果监听到全连接队列有数据可读，取出放入
        if(FD_ISSET(socketFD,&cur_set)){

            AcceptNewClient(&size,clients,socketFD,&source_set);

        }
        SendToEveryone(&size,clients,&cur_set,&source_set);

        CheckOutTimeClient(&size,clients,&source_set);

    }
    close(socketFD);
    return 0;
}
